/*  */
#include <iostream>
#include <fstream>
#include <log4cpp/Appender.hh>
#include <log4cpp/Category.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/RollingFileAppender.hh>
#include <log4cpp/Layout.hh>
#include <log4cpp/BasicLayout.hh>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/Priority.hh>
#include <string>
using std::string;
using std::cout;
using std::endl;
using std::ofstream;
using namespace log4cpp;
//拼接msg
#define  MSG(msg) string("[").append(__FILE__).append(":")\
         .append(__func__).append(":").append(std::to_string(__LINE__))\
         .append("]").append(msg).c_str()

#define LogInfo(msg) Mylogger::getInstance()->info(MSG(msg))
#define LogError(msg) Mylogger::getInstance()->error(MSG(msg))
#define LogWarn(msg) Mylogger::getInstance()->error(MSG(msg)) 
#define LogDebug(msg) Mylogger::getInstance()->debug(MSG(msg))

//log4cpp单例模式
class Mylogger
{
public:
    static Mylogger * getInstance(){
        if (ms_instance == nullptr) {
            ms_instance = new Mylogger();
        }
        return ms_instance;
    }
    static int destroy() {
        if (ms_instance != nullptr) {
            delete ms_instance;
            ms_instance = nullptr;
        }
        return 0;
    }
    inline void warn(const char *msg) {
        m_category.warn(msg);
    }
    void error(const char *msg) {
        m_category.error(msg);
    }
    void debug(const char *msg) {
        m_category.debug(msg);
    }
    void info(const char *msg) {
        m_category.info(msg);
    }
    void fatal(const char *msg) {
        m_category.fatal(msg);
    }
    void crit(const char *msg) {
        m_category.crit(msg);
    }

private:
    //私有记录器
    Category & m_category;
    static Mylogger * ms_instance;
    //删除拷贝构造和复值运算符函数
    Mylogger & operator=(const Mylogger& rsf) = delete;
    Mylogger(const Mylogger& rsf) = delete;
    //私有构造函数和析构函数
    Mylogger()
        :m_category(Category::getInstance("instance"))
    {
        //控制台输出器
        //new一个输出器
        OstreamAppender * appender = new OstreamAppender("console", &cout);
        //new一个格式器
        PatternLayout * layout = new PatternLayout();
        //自定义格式器
        layout->setConversionPattern("%c %d [%p] %m%n");
        //输出器绑定格式器
        appender->setLayout(layout);

        //回卷文件输出器
        //new一个输出器
        RollingFileAppender * appender3 = new RollingFileAppender("rolling", "instance.log", 100, 3);
        //new一个格式器
        PatternLayout * layout3 = new PatternLayout();
        //自定义格式器
        layout3->setConversionPattern("%c %d [%p] %m%n");
        //输出器绑定格式器
        appender3->setLayout(layout3);

        //设置优先级(添加过滤器),记录器绑定输出器
        m_category.setPriority(Priority::DEBUG);
        m_category.addAppender(appender);
        m_category.addAppender(appender3);
    }
    ~Mylogger() {
        Category::shutdown();
    }

private:
    //......
};//end of class Mylogger;
  //静态成员初始化
Mylogger * Mylogger::ms_instance = nullptr;
void test0()
{
    //第一步，完成单例模式的写法
    Mylogger *log = Mylogger::getInstance();

    log->info("The log is info message");
    log->error("The log is error message");
    log->fatal("The log is fatal message");
    log->crit("The log is crit message");
}

void test1() 
{
    printf("hello,world\n");
    //第二步，像使用printf一样
    //只要求能输出纯字符串信息即可，不需要做到格式化输出
    LogInfo("The log is info message");
    LogError("The log is error message");
    LogWarn("The log is warn message");
    LogDebug("The log is debug message");
   }
int main()
{
    test0();
    cout << "-----------------"<< endl;
    test1();
    Mylogger::destroy();
    return 0;
}

